import java.io.*;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Stack;
import java.util.Random;
import java.lang.Math;
import java.lang.String;

public class Hand{
	private Card[] cards;
	int count;				// amount of cards in hand
	private int[] value;
	
	public Hand(){
		cards = new Card[2];
		count = 0;
		value = new int[6];
		for(int i=0; i<6; i++)
		{
			value[i] = 0;
		}
	}
	public Hand(Card[] c)
	{
		cards = new Card[5];
		for(int i=0; i<5; i++)
		{
			cards[i] = new Card(c[i].getNumber(), c[i].getSuit());
		}
    	value = new int[6];
    	for(int i=0; i<6; i++)
    	{
    		value[i] = 0;
    	}
    	calcValue();
	}
	
	public void receiveCard( Card c ){
		if ( count < 2 ){
			cards[count] = c;
			count++;
		}
		if(count == 2)
		{
			calcValue();
		}
	}
	public int compareTo(Hand that)
    {
        for (int x=0; x<6; x++)
        {
            if (this.value[x]>that.value[x])
                return 1;
            else if (this.value[x]<that.value[x])
                return -1;
        }
        return 0; //if hands are equal
    }
	
	public Card viewCard( int i ){
		Card c = new Card();
		if (i < count){
			c = cards[i];
		}
		// if they are requestion a card that they do not own
		// let them know and then give them the topmost card they have
		else{
			System.out.println("That Card does not exist, top card is");
			c = cards[count-1];
		}
		return c;
	}	
		
	public void setCard( int i, Card c ){
		cards[i] = c;
	}
	
	public int getAmountOfCards(){
		return count;
	}
	
	public boolean isHandEmpty(){
		boolean b = false;
		if (count == 0){
			b = true;
		}
		return b;
	}
	public String toString()
	{
		String toReturn = "Your best hand is as follows...\n";
		toReturn += cards[0].toString() + " \n";
		toReturn += cards[1].toString() + " \n";
		toReturn += cards[2].toString() + " \n";
		toReturn += cards[3].toString() + " \n";
		toReturn += cards[4].toString() + " \n";
		toReturn += value[0] + " \n";
		toReturn += value[1] + " \n";
		toReturn += value[2] + " \n";
		toReturn += value[3] + " \n";
		toReturn += value[4] + " \n";
		toReturn += value[5] + " \n";
		
		return toReturn;
	}
	private void calcValue()
    {
    	int[] ranks = new int[14];
        //miscellaneous cards that are not otherwise significant
        int[] orderedRanks = new int[5];
        boolean flush=true, straight=false;
        int sameCards=1,sameCards2=1;
        int largeGroupRank=0,smallGroupRank=0;
        int index=0;

        for (int x=0; x<=13; x++)
        {
            ranks[x]=0;
        }
        for (int x=0; x<=4; x++)
        {
            ranks[ cards[x].getNumber() ]++;
        }
        for (int x=0; x<4; x++) {
            if ( cards[x].getSuit() != cards[x+1].getSuit() )
                flush=false;
        }

        for (int x=13; x>=1; x--)
        {
                 if (ranks[x] > sameCards)
                 {
                     if (sameCards != 1)
                     //if sameCards was not the default value
                     {
                         sameCards2 = sameCards;
                         smallGroupRank = largeGroupRank;
                     }

                     sameCards = ranks[x];
                     largeGroupRank = x;

                 } else if (ranks[x] > sameCards2)
                 {
                     sameCards2 = ranks[x];
                     smallGroupRank = x;
                 }
        }

        if (ranks[1]==1) //if ace, run this before because ace is highest card
        {
            orderedRanks[index]=14;
            index++;
        }

        for (int x=13; x>=2; x--)
        {
            if (ranks[x]==1)
            {
                orderedRanks[index]=x; //if ace
                index++;
            }
        }
        
        for (int x=1; x<=9; x++)
        //can't have straight with lowest value of more than 10
        {
            if (ranks[x]==1 && ranks[x+1]==1 && ranks[x+2]==1 && 
                ranks[x+3]==1 && ranks[x+4]==1)
            {
                straight=true;
                break;
            }
        }

        if (ranks[10]==1 && ranks[11]==1 && ranks[12]==1 && 
            ranks[13]==1 && ranks[1]==1) //ace high
        {
            straight=true;
        }
        
        for (int x=0; x<=5; x++)
        {
            value[x]=0;
        }


        //start hand evaluation
        if ( sameCards==1 ) {
            value[0]=1;
            value[1]=orderedRanks[0];
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }

        if (sameCards==2 && sameCards2==1)
        {
            value[0]=2;
            value[1]=largeGroupRank; //rank of pair
            value[2]=orderedRanks[0];
            value[3]=orderedRanks[1];
            value[4]=orderedRanks[2];
            value[5]=orderedRanks[3];
        }

        if (sameCards==2 && sameCards2==2) //two pair
        {
            value[0]=3;
            //rank of greater pair
            value[1]= largeGroupRank>smallGroupRank ? largeGroupRank : smallGroupRank;
            value[2]= largeGroupRank<smallGroupRank ? largeGroupRank : smallGroupRank;
            value[3]=orderedRanks[0];  //extra card
        }

        if (sameCards==3 && sameCards2!=2)
        {
            value[0]=4;
            value[1]= largeGroupRank;
            value[2]=orderedRanks[0];
            value[3]=orderedRanks[1];
        }

        if (straight && !flush)
        {
            value[0]=5;
            value[1]=orderedRanks[0]; //tie determined by ranks of cards
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }

        if (flush && !straight)
        {
            value[0]=6;
            value[1]=orderedRanks[0]; //tie determined by ranks of cards
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }

        if (sameCards==3 && sameCards2==2)
        {
            value[0]=7;
            value[1]=largeGroupRank;
            value[2]=smallGroupRank;
        }

        if (sameCards==4)
        {
            value[0]=8;
            value[1]=largeGroupRank;
            value[2]=orderedRanks[0];
        }

        if (straight && flush)
        {
            value[0]=9;
            value[1]=orderedRanks[0]; //tie determined by ranks of cards
            value[2]=orderedRanks[1];
            value[3]=orderedRanks[2];
            value[4]=orderedRanks[3];
            value[5]=orderedRanks[4];
        }
    }
}